using System.Data.Common;
using Microsoft.EntityFrameworkCore;
using UniversalAdmin.Application.Common;
using UniversalAdmin.Application.Dtos;
using UniversalAdmin.Application.Dtos.Log;
using UniversalAdmin.Domain.Entities.App;
using UniversalAdmin.Domain.Repositories;
using MediatR;
using UniversalAdmin.Application.Services.Interfaces;

namespace UniversalAdmin.Application.Services;

public class UserService : IUserService
{
    private readonly IRepositories<User> _userRepositories;
    private readonly IRepositories<Role> _roleRepositories;
    private readonly IMediator _mediator;
    private readonly ILogService _logService;

    public UserService(IRepositories<User> userRepositories, IRepositories<Role> roleRepositories, IMediator mediator, ILogService logService)
    {
        _userRepositories = userRepositories;
        _roleRepositories = roleRepositories;
        _mediator = mediator;
        _logService = logService;
    }
    // 分配角色
    public async Task<string> AssignRoleAsync(Guid userId, Guid roleId)
    {
        // 查找用户
        var user = await _userRepositories.GetByIdAsync(userId);
        if (user == null)
        {
            throw new Exception($"用户不存在，用户ID: {userId}");
        }
        if (user.IsActive == false)
        {
            throw new Exception("用户已被禁用");
        }

        // 查找角色
        var role = await _roleRepositories.GetByIdAsync(roleId);
        if (role == null)
        {
            throw new Exception($"角色不存在，角色ID: {roleId}");
        }
        if (role.IsActive == false)
        {
            throw new Exception("角色已被禁用");
        }

        // 检查用户是否已分配该角色
        var hasRole = user.Roles.Any(r => r.Id == roleId);
        if (hasRole)
        {
            var userRoles = string.Join(", ", user.Roles.Select(r => $"{r.Name}({r.Id})"));
            throw new Exception($"用户 {user.Username} 已分配角色 {role.Name}。用户当前角色: {userRoles}");
        }

        // 分配角色
        user.AssigRole(role);
        user.UpdatedAt = DateTime.UtcNow;
        await _userRepositories.UpdateAsync(user);

        // 记录日志
        await _logService.AddAsync(new CreateLogDto
        {
            UserId = user.Id,
            Action = "AssignRole",
            Resource = "User",
            ResourceId = user.Id
        });

        return "角色分配成功";
    }

    public async Task<string> CreateAsync(UsersDto dto)
    {
        Console.WriteLine($"roleId  = {dto.RoleId}");

        // 确定要分配的角色
        Role? roleToAssign = null;

        if (dto.RoleId != Guid.Empty)
        {
            // 如果指定了角色ID，使用指定的角色
            roleToAssign = (await _roleRepositories.GetAllAsync()).FirstOrDefault(r => r.Id == dto.RoleId);
            if (roleToAssign == null)
            {
                throw new Exception($"指定的角色不存在，角色ID: {dto.RoleId}");
            }
            Console.WriteLine($"使用指定角色: {roleToAssign.Name}");
        }
        else
        {
            // 如果没有指定角色ID，使用默认角色
            roleToAssign = (await _roleRepositories.GetAllAsync()).FirstOrDefault(r => r.Name == "普通用户");
            if (roleToAssign == null)
            {
                throw new Exception("默认角色不存在，请确保数据库中已创建User角色");
            }
            Console.WriteLine($"使用默认角色: {roleToAssign.Name}");
        }

        var exists = (await _userRepositories.GetAllAsync()).Any(u => u.Username == dto.Username);
        if (exists)
        {
            return "用户名已存在";
        }
        var hashedPwd = HashPassword(dto.Password);

        var user = new User
        {
            Id = Guid.NewGuid(),
            Username = dto.Username,
            Password = hashedPwd,
            Email = dto.Email ?? string.Empty,
            Phone = dto.Phone,
            IsActive = true,
            CreatedAt = DateTime.UtcNow,
            UpdatedAt = DateTime.UtcNow
        };

        // 分配角色
        user.AssigRole(roleToAssign);
        Console.WriteLine($"用户 {user.Username} 已分配角色: {roleToAssign.Name}");

        await _userRepositories.CreateAsync(user);
        // 发布领域事件
        await _mediator.Publish(new UserCreatedEvent(user));
        return "新增成功";
    }

    public async Task<string> DeleteAsync(Guid id)
    {
        var user = await _userRepositories.GetByIdAsync(id);

        if (user == null)
        {
            return "没有该用户";
        }

        // 在删除前触发删除事件
        await _mediator.Publish(new UserDeletedEvent(user));

        user.UpdatedAt = DateTime.UtcNow;
        await _userRepositories.DeleteAsync(user);
        return "删除成功";
    }
    // 禁用
    public async Task<string> DisableAsync(Guid id)
    {
        var user = await _userRepositories.GetByIdAsync(id);
        if (user == null)
        {
            return "用户不存在或已经删除";
        }
        if (user.IsActive == false)
        {
            return "用户已被禁用";
        }
        user.IsActive = false;
        user.UpdatedAt = DateTime.UtcNow;
        await _userRepositories.UpdateAsync(user);

        return "用户已被禁用";
    }
    // 启用
    public async Task EnableAsync(Guid id)
    {
        var user = await _userRepositories.GetByIdAsync(id);
        if (user == null)
        {
            throw new Exception("用户不存在或已经删除");
        }
        if (user.IsActive)
        {
            throw new Exception("用户已被启用");
        }
        user.IsActive = true;
        user.UpdatedAt = DateTime.UtcNow;
        await _userRepositories.UpdateAsync(user);
    }

    public async Task<IEnumerable<UsersDto>> GetAllAsync(PageRequestDto PageRequestDto)
    {
        // 获取用户列表，包含角色信息
        var users = await _userRepositories.GetPagedAsync(PageRequestDto.PageIndex, PageRequestDto.PageSize);
        
        var usersWithRoles = new List<UsersDto>();
        foreach (var user in users)
        {
            var firstRole = user.Roles.FirstOrDefault();
            var userDto = new UsersDto
            {
                Id = user.Id,
                Username = user.Username,
                Password = user.Password,
                Email = user.Email,
                Phone = user.Phone,
                Avatar = user.Avatar,
                IsActive = user.IsActive,
                RoleId = firstRole != null ? firstRole.Id : Guid.Empty,
                Roles = user.Roles.Select(r => new RoleInfo
                {
                    Id = r.Id,
                    Name = r.Name,
                    Description = r.Description ?? string.Empty,
                    IsActive = r.IsActive
                }).ToList()
            };
            usersWithRoles.Add(userDto);
        }

        // 只写一条日志
        await _logService.AddAsync(new CreateLogDto
        {
            Action = "QueryList",
            Resource = "User"
            // 可补充UserId、Ip等
        });

        return usersWithRoles;
    }

    public async Task<UsersDto> GetByIdAsync(Guid id)
    {
        var user = await _userRepositories.GetByIdAsync(id);
        if (user == null)
        {
            return null!;
        }
        var obj = new UsersDto
        {
            Username = user.Username,
            Password = user.Password
        };
        await _mediator.Publish(new UserQueriedEvent(user));
        return obj;
    }

    public async Task<UsersDto?> GetByUsernameAsync(string username)
    {
        var user = await _userRepositories.GetByUsernameAsync(username);
        if (user == null)
        {
            return null;
        }
        var obj = new UsersDto
        {
            Id = user.Id,
            Username = user.Username,
            Email = user.Email ?? string.Empty,
            Phone = user.Phone,
            Avatar = user.Avatar
        };
        await _mediator.Publish(new UserQueriedEvent(user));
        return obj;
    }

    public async Task<IEnumerable<UsersDto>> GetByUsernameFuzzyAsync(string username)
    {
        // 使用模糊查询获取用户列表
        var users = await _userRepositories.Table
            .OfType<User>()
            .Include(u => u.Roles)
            .Where(u => u.Username.Contains(username))
            .ToListAsync();

        var usersWithRoles = new List<UsersDto>();
        foreach (var user in users)
        {
            var firstRole = user.Roles.FirstOrDefault();
            var userDto = new UsersDto
            {
                Id = user.Id,
                Username = user.Username,
                Password = user.Password,
                Email = user.Email,
                Phone = user.Phone,
                Avatar = user.Avatar,
                IsActive = user.IsActive,
                RoleId = firstRole != null ? firstRole.Id : Guid.Empty,
                Roles = user.Roles.Select(r => new RoleInfo
                {
                    Id = r.Id,
                    Name = r.Name,
                    Description = r.Description ?? string.Empty,
                    IsActive = r.IsActive
                }).ToList()
            };
            usersWithRoles.Add(userDto);
        }

        return usersWithRoles;
    }

    public async Task<dynamic> GetUserWithRolesAsync(Guid userId)
    {
        // 先获取用户基本信息
        var user = await _userRepositories.GetByIdAsync(userId);
        if (user == null)
        {
            return new { error = "用户不存在" };
        }

        // 手动查询用户的角色信息
        var userRoles = await _userRepositories.Table
            .OfType<User>()
            .Where(u => u.Id == userId)
            .SelectMany(u => u.Roles)
            .Select(r => new
            {
                Id = r.Id,
                Name = r.Name,
                Description = r.Description,
                IsActive = r.IsActive
            })
            .ToListAsync();

        return new
        {
            UserId = user.Id,
            Username = user.Username,
            Email = user.Email,
            Phone = user.Phone,
            Avatar = user.Avatar,
            IsActive = user.IsActive,
            Roles = userRoles,
            RoleCount = userRoles.Count
        };
    }

    public async Task RemoveRoleAsync(Guid userId, Guid roleId)
    {
        // 查找用户
        var user = await _userRepositories.GetByIdAsync(userId);
        if (user == null)
        {
            throw new Exception($"用户不存在，用户ID: {userId}");
        }

        // 查找角色
        var role = await _roleRepositories.GetByIdAsync(roleId);
        if (role == null)
        {
            throw new Exception($"角色不存在，角色ID: {roleId}");
        }

        // 调试信息：打印用户和角色的详细信息
        Console.WriteLine($"调试信息 - 用户: {user.Username} (ID: {user.Id})");
        Console.WriteLine($"调试信息 - 角色: {role.Name} (ID: {role.Id})");
        Console.WriteLine($"调试信息 - 用户当前角色数量: {user.Roles.Count}");

        // 检查用户是否已分配该角色
        var hasRole = user.Roles.Any(r => r.Id == roleId);
        if (!hasRole)
        {
            var userRoles = string.Join(", ", user.Roles.Select(r => $"{r.Name}({r.Id})"));
            throw new Exception($"用户 {user.Username} 未分配角色 {role.Name}。用户当前角色: {userRoles}");
        }

        // 移除角色
        user.RemoveRole(role);
        user.UpdatedAt = DateTime.UtcNow;

        // 保存更改
        await _userRepositories.UpdateAsync(user);

        // 记录日志
        await _logService.AddAsync(new CreateLogDto
        {
            UserId = user.Id,
            Action = "RemoveRole",
            Resource = "User",
            ResourceId = user.Id
        });
    }

    public async Task<string> UpdateAsync(Guid id, UsersDto dto)
    {
        Console.WriteLine($"dto  = {dto}");

        // 查找用户（包含角色信息）
        var user = await _userRepositories.Table
            .OfType<User>()
            .Include(u => u.Roles)
            .FirstOrDefaultAsync(u => u.Id == id);
            
        if (user == null)
        {
            return "用户不存在";
        }
        if (user.IsActive == false)
        {
            return "用户已被禁用";
        }

        // 更新基本信息
        var hashedPwd = HashPassword(dto.Password);
        user.Username = dto.Username;
        user.Password = hashedPwd;
        user.Email = dto.Email;
        user.Phone = dto.Phone;
        user.IsActive = dto.IsActive;
        user.UpdatedAt = DateTime.UtcNow;

        // 处理角色更新
        if (dto.RoleId != Guid.Empty)
        {
            // 查找要分配的角色
            var newRole = await _roleRepositories.GetByIdAsync(dto.RoleId);
            if (newRole == null)
            {
                return "指定的角色不存在";
            }
            if (!newRole.IsActive)
            {
                return "指定的角色已被禁用";
            }

            // 清除用户当前的所有角色
            user.Roles.Clear();

            // 分配新角色
            user.AssigRole(newRole);
            
            Console.WriteLine($"用户 {user.Username} 的角色已更新为: {newRole.Name}");
        }

        await _userRepositories.UpdateAsync(user);
        await _mediator.Publish(new UserUpdatedEvent(user));
        return "更新成功";
    }

    private string HashPassword(string password)
    {
        // 简单示例，实际请用更安全的哈希算法
        using var sha256 = System.Security.Cryptography.SHA256.Create();
        var bytes = System.Text.Encoding.UTF8.GetBytes(password);
        var hash = sha256.ComputeHash(bytes);
        return Convert.ToBase64String(hash);
    }
}